const { ccclass, property } = cc._decorator;

@ccclass
export default class Main extends cc.Component {
    @property(cc.Label)
    scope: cc.Label;
    @property(cc.Label)
    maxScope: cc.Label;
    @property(cc.Node)
    pongo: cc.Node;
    @property(cc.Prefab)
    star: cc.Prefab;
    @property(cc.Prefab)
    redstar: cc.Prefab;
    @property(cc.AudioClip)
    pickAudio: cc.AudioClip;
    @property(cc.AudioClip)
    bgAudio: cc.AudioClip;
    @property(cc.Node)
    bgImage: cc.Node;
    @property(cc.Node)
    allBg: cc.Node;
    newStar: cc.Node;
    newRedStar: cc.Node;
    jumpHeight = 100;
    jumpDuration = 0.45;
    maxMoveSpeed = 400;
    accel = 450;

    xSpeed = 0;
    accLeft = false;
    accRight = false;

    maxStarDuration: 0;
    minStarDuration: 0;
    pickRadius: 100;
    scopeNum = 0;
    maxScopeNum = 0;
    isRoll = false;

    ss;

    @property(cc.CircleCollider)
    collider: cc.CircleCollider;

    start() {
        let jumpAction = this.runJumpAction();
        this.ss = cc.tween(this.pongo).then(jumpAction);
        this.ss.start();
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
        this.spawnNewStar();
        this.spawnNewRedStar();
        this.schedule(() => this.moveNewRedStar(), 5);
        this.createBgImage();
        let manager = cc.director.getCollisionManager();
        manager.enabled = true;
        this.pongo.on('eatStar', (msg) => {
            if (msg === 'star') {
                this.onPicked();
            }
            if (msg === 'redstar') {
                this.onPickRed();
            }
        });
    }

    runJumpAction() {
        let jumpUp = cc.tween().by(this.jumpDuration, { y: this.jumpHeight }, { easing: 'sineOut' });
        let jumpDown = cc.tween().to(this.jumpDuration, { y: -200 }, { easing: 'sineIn' });

        let sequence = cc
            .tween()
            .sequence(jumpUp, jumpDown)
            .call(() => this.playBgSound());
        return cc.tween().repeatForever(sequence).start();
    }
    runRollAction() {
        cc.tween(this.pongo).by(1, { angle: -360 }).start();
        this.isRoll = false;
    }

    jumpUpAction() {
        this.ss.stop();
        this.jumpHeight = 100;
        this.ss.start();
    }

    jumpDownAction() {
        this.ss.stop();
    }

    spawnNewStar() {
        let newStar = cc.instantiate(this.star);
        newStar.parent = this.node;
        newStar.x = Math.random() * 400 - 200;
        newStar.y = Math.random() * 300 - 200;
        this.newStar = newStar;
    }
    spawnNewRedStar() {
        let newStar = cc.instantiate(this.redstar);
        newStar.parent = this.node;
        newStar.x = Math.random() * 200;
        newStar.y = Math.random() * 100;
        this.newRedStar = newStar;
    }
    moveNewRedStar() {
        this.newRedStar.active = true;
        this.newRedStar.x = Math.random() * 400 - 200;
        this.newRedStar.y = Math.random() * 300 - 200;
    }

    getDistance(starname) {
        let pongoPos = this.pongo.getPosition();
        let starPos = this.node.getChildByName(starname).getPosition();
        let dis = pongoPos.sub(starPos).mag();
        return dis;
    }

    onPicked() {
        this.node.getChildByName('star').x = Math.random() * 400 - 200;
        this.node.getChildByName('star').y = Math.random() * 300;
        this.scopeNum += 100;
        this.scope.string = this.scopeNum + '';
        if (this.scopeNum > this.maxScopeNum) {
            this.maxScopeNum = this.scopeNum;
            this.maxScope.string = this.maxScopeNum + '';
        }
        this.pongo.scaleX += 0.1;
        this.pongo.scaleY += 0.1;
        this.playScopeSound();
    }
    onPickRed() {
        if (this.newRedStar.active) {
            this.scopeNum -= 100;
            this.scope.string = this.scopeNum + '';
            this.newRedStar.active = false;
            if (this.pongo.scaleX >= 1) {
                this.pongo.scaleX -= 0.2;
            }
            if (this.pongo.scaleY >= 1) {
                this.pongo.scaleY -= 0.2;
            }
        }
    }
    playBgSound() {
        cc.audioEngine.playEffect(this.bgAudio, false);
    }
    playScopeSound() {
        cc.audioEngine.playEffect(this.pickAudio, false);
    }
    createBgImage() {
        let newImage = cc.instantiate(this.bgImage);
        newImage.parent = this.allBg;
        newImage.x = 0;
        newImage.y = 640;
    }
    update(dt) {
        if (this.accLeft) {
            this.xSpeed -= this.accel * dt;
            this.pongo.scaleX = -1;
        } else if (this.accRight) {
            this.xSpeed += this.accel * dt;
            this.pongo.scaleX = 1;
        }

        if (Math.abs(this.xSpeed) > this.maxMoveSpeed) {
            this.xSpeed = (this.maxMoveSpeed * this.xSpeed) / Math.abs(this.xSpeed);
        }
        this.pongo.x += this.xSpeed * dt;
        if (this.pongo.x >= 390) {
            this.pongo.x = -380;
        }
        if (this.pongo.x <= -390) {
            this.pongo.x = 380;
        }
        if (this.pongo.y >= 280) {
            this.pongo.y = 230;
        }
        if (this.pongo.y <= -280) {
            this.pongo.y = -230;
        }
        if (this.node.getChildByName('star').y > -200) {
            this.node.getChildByName('star').y -= 1;
        }

        if (this.scopeNum > 0) {
            this.scopeNum -= 1;
            this.scope.string = this.scopeNum + '';
        }
        if (this.isRoll) {
            this.runRollAction();
        }
        for (let i = 0; i < this.allBg.children.length; i++) {
            this.allBg.children[i].y--;
        }
        if (this.allBg.children[1].y == 0) {
            this.allBg.children[0].y = 640;
        }
        if (this.allBg.children[0].y == 0) {
            this.allBg.children[1].y = 640;
        }
    }

    onKeyDown(event) {
        switch (event.keyCode) {
            case cc.macro.KEY.a:
                this.accLeft = true;
                this.accRight = false;
                break;
            case cc.macro.KEY.d:
                this.accLeft = false;
                this.accRight = true;
                break;
            case cc.macro.KEY.w:
                this.jumpUpAction();
                break;
            case cc.macro.KEY.s:
                this.jumpDownAction();
                break;
            case cc.macro.KEY.left:
                this.accLeft = true;
                this.accRight = false;
                break;
            case cc.macro.KEY.right:
                this.accLeft = false;
                this.accRight = true;
                break;
            case cc.macro.KEY.space:
                this.isRoll = true;
                break;
        }
    }

    onKeyUp(event) {
        switch (event.keyCode) {
            case cc.macro.KEY.a:
                this.accLeft = false;
                break;
            case cc.macro.KEY.d:
                this.accRight = false;
                break;
        }
    }

    onDestroy() {
        cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
        cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
    }
}
